#include "pd_TCPfile.hpp"

static const string PROBLEM_DIR_NOT_FOUND_OR_INVALID = "problem dir not found or invalid";
static const string PROBLEM_DIR_CANNOT_BE_CREATED = "problem dir cannot be created";

/*
 * write string to file
 * para: const string& fileName, const string content
 * return: pair<bool, string>: code, content; code true, or code false with error info
 */
pair<bool, string> WriteStringTofile(const string& fileName, const string content){
	/****************************open and write string*****************************/
    fstream s(fileName, s.out|s.trunc);    //truncate the old content
    if (!s.is_open()) {
        return pair<bool, string>{false, (string)"WriteStringTofile: cannot open target file for write!, filename is:" + fileName};
    } else {
        s << content;
        s.close();
        return pair<bool, string>{true, ""};
    }
}

/*
 * read data content to string
 * input: const string& fileName
 * return pair<bool, string>: code, content; code true with file content, or code false with error info
 */
pair<bool, string> ReadFileToString(const string& fileName)
{
    fstream s(fileName, s.in);
    if (!s.is_open()) {
        return {false, "ReadFileToString: cannot find " + fileName};
    } else {
        ostringstream tmp;
        tmp << s.rdbuf();   
        s.close();
        return {true, tmp.str()};
    }
}

/*
 * check and generate directory of testcase
 * para: const string raw, string& blockName, string& problemName, string& languageStr
 * return pair<bool, string>: code, content; code true with "", or code false with error info
 *
 * note: the function exec: check raw, generate blockName and problemName from raw; create dir of blockName, blockName/problemName, blockName/problemName/languageStr
 */
pair<bool, string> CheckAndGenerateDirOfTestcase(const string raw, string& blockName, string& problemName, string languageStr){
	//split with /, check if it is valid
	int sSlicePos = raw.find_first_of("/");
	if ((size_t)sSlicePos == raw.npos) return {false, PROBLEM_DIR_NOT_FOUND_OR_INVALID};
	
	blockName = raw.substr(0, sSlicePos);
	problemName = raw.substr(sSlicePos + 1);
	regex blockRe("[a-zA-Z][a-zA-Z0-9_]{3,20}");
	regex problemRe("[a-zA-Z][a-zA-Z0-9_]{3,50}");
	
	if ((!regex_match(blockName, blockRe)) || (!regex_match(problemName, problemRe))) return {false, PROBLEM_DIR_NOT_FOUND_OR_INVALID};
	
	//create dir if not occur
	DIR* tempDir;
	tempDir = opendir(blockName.c_str());   //find parent directory
	if (tempDir) closedir(tempDir);        //Directory already exist
	else if (ENOENT == errno)
	{
		int flag = mkdir(blockName.c_str(), 0744);
		if (flag != 0) return {false, PROBLEM_DIR_CANNOT_BE_CREATED};
	}
	else return {false, PROBLEM_DIR_CANNOT_BE_CREATED};
	
	tempDir = opendir((blockName + "/" + problemName).c_str());   //find parent directory
	if (tempDir) closedir(tempDir);        //Directory already exist
	else if (ENOENT == errno)
	{
		int flag = mkdir((blockName + "/" + problemName).c_str(), 0744);
		if (flag != 0) return {false, PROBLEM_DIR_CANNOT_BE_CREATED};
	}
	else return {false, PROBLEM_DIR_CANNOT_BE_CREATED};
	
	tempDir = opendir((blockName + "/" + problemName + "/" + languageStr).c_str());   //find parent directory
	if (tempDir) closedir(tempDir);        //Directory already exist
	else if (ENOENT == errno)
	{
		int flag = mkdir((blockName + "/" + problemName + "/" + languageStr).c_str(), 0744);
		if (flag != 0) return {false, PROBLEM_DIR_CANNOT_BE_CREATED};
	}
	else return {false, PROBLEM_DIR_CANNOT_BE_CREATED};
	
	//everything ok
	return {true, ""};
}

